#include "SIM808.h"

SIM808::SIM808(){
	fd=0;
	call_fd = NULL;
	sms_fd = NULL;
	i=0;
	strcpy(judge_arr,"");
	strcpy(call_num,"");
	strcpy(sms_num,"");
	strcpy(sms_com,"");
	strcpy(call_com,"");
	strcpy(content,"");
	strcat(content, "I'm in trouble.I need your help.  \nGPS data:");
	strcpy(gps_inf,"");
}
void SIM808::set_callcom(char *callnum){//设置打电话命令
	strcpy(call_com,"ATD");
	strcat(call_com,callnum);//拼接打电话命令
	strcat(call_com,";\r\n");
}

void SIM808::set_smscom(char *smsnum){//设置短信命令
	strcpy(sms_com,"AT+CMGS=\"");
	strcat(sms_com,smsnum);//拼接发送短信命令
	strcat(sms_com, "\"");
	strcat(sms_com,"\r\n");
}

void SIM808::judge_sms(){//判断是否有新短信
	printf("SIM808:judge_sms: Start!\n");
	char str_CPMS[60];//短信数量字符串
	char str_CMGR[600];//短信内容
	char str_smsnum[10];//短信数量
	char readsms_com[25];//读取短信内容命令
	char deletesms_com[25];//删除短信命令
	int sms_sum = 0;
	char *p;
	strcpy(str_CPMS,"");//清空数组
	strcpy(str_CMGR,"");//清空数组
	strcpy(str_smsnum,"");//清空数组
	strcpy(readsms_com,"");//清空数组
	serialFlush(fd); //清空串口缓冲区
	delay(200);
	printf("SIM808:judge_sms: CPMS frist!\n");
	serialPuts(fd,"AT+CPMS?\r\n");//获取短信数量
	printf("SIM808:judge_sms: CPMS end!\n");
	delay(200);
	if(read(fd,str_CPMS,50) <= 0){
		printf("SIM808:judge_sms: Error reading serial port, cannot judge sms num\n");
		return ;
	}
	i = 0;
	printf("\n");
	while (str_CPMS[i] != 0) { //打印接受到的数据
		printf("%c",str_CPMS[i]);
		i++;
	}
	printf("\n");
	printf("SIM808:judge_sms: CPMS_str printf end!\n");
	p = (char *)strtok(str_CPMS, ","); //根据“,”分割字符串
	if(p == NULL){
		printf("SIM808:judge_sms: Error reading cpms data from serial port, cannot judge sms num\n");
		return ;
	}
	p = (char *)strtok(NULL, ",");
	if(p == NULL){
		printf("SIM808:judge_sms: Error reading cpms data from serial port, cannot judge sms num\n");
		return ;
	}
	strcpy(str_smsnum, p);
	printf("SIM808:judge_sms: Recv STR_SMSNUM: ");printf(str_smsnum);printf("\n");
	sms_sum = atoi(str_smsnum);//获取短信数量
	printf("SIM808:judge_sms: Recv SMS_NUM: %d\n",sms_sum);
	if(sms_sum <= 0){
		printf("SIM808:judge_sms: no new sms\n");
		return;
	}
	while(sms_sum > 0){//处理每条短信
		strcpy(str_smsnum,"");
		sprintf(str_smsnum,"%d",sms_sum);
		strcpy(readsms_com,"AT+CMGR=");
		strcat(readsms_com,str_smsnum);//拼接读取短信命令
		strcat(readsms_com,"\r\n");
		serialFlush(fd); //清空串口缓冲区
		serialPuts(fd,readsms_com);
		printf("SIM808:judge_sms: Send Read sms com\n");
		delay(500);//等待数据接收完全
		if (serialDataAvail(fd) > 0) {//串口有数据 对短信进行处理
			strcpy(str_CMGR,"");//清空数组
			read(fd,str_CMGR,500);//读取串口数据
			i = 0;
			while (str_CMGR[i] != 0) { //打印接受到的数据
				printf("%c",str_CMGR[i]);
				i++;
			}
			printf("\n");
			if((p = strstr(str_CMGR, "set call num:")) != NULL){//设置打电话号码
				p = p + 13;//跳转到号码处
				strcpy(call_num, "");
				printf("SIM808:judge_sms: call_num: ");
				for(int i = 0; i < 11; i++){  
					call_num[i] = p[i];
					printf("%c",call_num[i]);
				}
				printf("\n");
				set_callcom(call_num);//设置打电话命令
				write_num(0, call_num);//将号码写入文件
			}
			if((p = strstr(str_CMGR, "set sms num:")) != NULL){//设置接收短信号码
				p = p + 12;//跳转到号码处
				strcpy(sms_num, "");
				printf("SIM808:judge_sms: sms_num: ");
				for(int i = 0; i < 11; i++){  
					sms_num[i] = p[i];
					printf("%c",sms_num[i]);
				}
				printf("\n");
				set_smscom(sms_num);//设置发短信命令
				write_num(1, sms_num);//将号码写入文件
			}
		}
		//删除当前短信
		strcpy(str_smsnum,"");
		sprintf(str_smsnum,"%d",sms_sum);
		strcpy(deletesms_com,"AT+CMGD=");
		strcat(deletesms_com,str_smsnum);//拼接删除短信命令
		strcat(deletesms_com,"\r\n");
		serialPuts(fd,deletesms_com);//发送删除短信命令
		sms_sum --;
	}
}

int SIM808::write_num(int index, char *num){//向文件中写入号码
	if(index == 0){//设置打电话文件
		call_fd = fopen(call_path, "w");
		if(call_fd == NULL) {//open file
			printf("SIM808:write_num: open call file failed\r\n");
			return 0;
		}
		printf("SIM808:write_call_num: ");
		for(int i=0; i<11; i++){
			fprintf(call_fd,"%c", num[i]);
			printf("%c",num[i]);
		}
		printf("\n");
		fclose(call_fd);
		return 1;
	}
	else if(index == 1){//设置发短信文件
		sms_fd = fopen(sms_path, "w");
		if(sms_fd == NULL) {//open file
			printf("SIM808:write_num: open call file failed\r\n");
			return 0;
		}
		printf("SIM808:write_sms_num: ");
		for(int i=0; i<11; i++){
			fprintf(sms_fd,"%c", num[i]);
			printf("%c",num[i]);
		}
		printf("\n");
		fclose(sms_fd);
		return 1;
	}
	else{
		printf("SIM808:write_num: index error!\r\n");
		return 0;
	}
}
int SIM808::read_num(){//从文件中读取号码
	call_fd = fopen(call_path, "r");
	if(call_fd == NULL) {//open file
		printf("SIM808:read_num: open call file failed\r\n");
		return 0;
	}
	sms_fd = fopen(sms_path, "r");
	if(sms_fd == NULL) {//open file
		printf("SIM808:read_num: open sms file failed\r\n");
		return 0;
	}
	printf("SIM808:read_num: call_num:");
	for(int i = 0; i < 11; i++){  
        fscanf(call_fd,"%c",&call_num[i]);
        printf("%c",call_num[i]);
    }
	printf("\n");
	fclose(call_fd);
	printf("SIM808:read_num: sms_num:");
	for(int i = 0; i < 11; i++){  
        fscanf(sms_fd,"%c",&sms_num[i]);
        printf("%c",sms_num[i]);
    }
	printf("\n");
	fclose(sms_fd);
	return 1;
}

int SIM808::All_Init(){//全部初始化
	fd=serialOpen("/dev/serial0",19200);//串口初始化
	delay(200);
	if(fd == -1){
		printf("SIM808:All_Init: Serial port initialization failed\n");
		return 0;
	}
	if(read_num() == 0){
		printf("SIM808:All_Init: read_num error!\n");
		return -1;
	}
	set_callcom(call_num);
	set_smscom(sms_num);
	if(set_smsmode() == 0){
		printf("SIM808:All_Init: set_sms_mode error!\n");
		return -2;
	}
	if(set_gpsmode() == 0){
		printf("SIM808:All_Init: set_gpsmode error!\n");
		return -3;
	}
	return 1;
}

int SIM808::judge_str(const char *p){
	strcpy(judge_arr,"");//清空数组
	if(read(fd,judge_arr,20) <= 0){
		printf("SIM808:judge_str: Error reading serial port, cannot judge OK\n");
		return 0;
	}
	if(strstr(judge_arr,p) != NULL){
		return 1;//找到OK
	}
	else{
		return 0;//没有找到ok
	}
}

int SIM808::set_smsmode(){//短信模式设置
  for (i = 0; i < 100; i++) {
    serialPuts(fd,"AT\r\n");
    printf("SIM808:set_smsmode: AT\n");
    delay(200);
    if (judge_str("OK")){
      printf("SIM808:set_smsmode: send AT OK!\n");
      break;
    }
  }
  if (i >= 100){
    printf("SIM808:set_smsmode: send AT error!\n");
    return 0;
  }
  else {
	serialPuts(fd,"ATE0\r\n");//取消回显
    while (judge_str("OK") == 0) {
      printf("SIM808:set_smsmode: send ATE0 wait!\n");
      delay(200);
    }
    printf("SIM808:set_smsmode: send ATE0 OK!\n");
    serialPuts(fd,"AT+CMGF=1\r\n");//发送TXT格式短信
    while (judge_str("OK") == 0) {
      printf("SIM808:set_smsmode: send AT+CMGF wait!\n");
      delay(200);
    }
    printf("SIM808:set_smsmode: send AT+CMGF OK!\n");
	serialPuts(fd,"AT+CMGDA=\"DEL ALL\"\r\n");//删除TXT模式下的所有短信
    while (judge_str("OK") == 0) {
      printf("SIM808:set_smsmode: send AT+CMGDA=\"DEL ALL\" wait!\n");
      delay(200);
    }
    printf("SIM808:set_smsmode: send AT+CMGDA=\"DEL ALL\" OK!\n");
    serialPuts(fd,"AT+CSCS=\"GSM\"\r\n");//采用GSM编码
    while (judge_str("OK") == 0) {
      printf("SIM808:set_smsmode: send AT+CSCS wait!\n");
      delay(200);
    }
    printf("SIM808:set_smsmode: send AT+CSCS=\"GSM\" OK!\n");
    serialPuts(fd,"AT+CSCA?\r\n");//获取短信中心号码
    while (judge_str("OK") == 0) {
      printf("SIM808:set_smsmode: send AT+CSCA wait!\n");
      delay(200);
    }
    printf("SIM808:set_smsmode: send AT+CSCA? OK!\n");
    serialPuts(fd,"AT+CSMP=17,167,0,240\r\n");//GSM格式下参数设置
    while (judge_str("OK") == 0) {
      printf("SIM808:set_smsmode: send AT+CSMP wait!\n");
      delay(200);
    }
    printf("SIM808:set_smsmode: send AT+CSMP OK!\n");
    return 1;
  }
}

int SIM808::set_gpsmode(){//gps模式设置
  for (i = 0; i < 100; i++) {
    serialPuts(fd,"AT+CGNSPWR=1\r\n");//开启GPS电源
    printf("SIM808:set_gpsmode: AT+CGNSPWR=1\n");
    delay(1000);
    if (judge_str("OK")) {
      printf("SIM808:set_gpsmode: turn on GPS power!\n");
      break;
    }
  }
  if (i >= 100) {
    printf("SIM808:set_gpsmode: turn on GPS power error!\n");
    return 0;
  }
  else {
    serialPuts(fd,"AT+CGNSSEQ=\"RMC\"\r\n");//定义NAME解析
    while (judge_str("OK") == 0) {
      printf("SIM808:set_gpsmode: send AT+CGNSSEQ wait!\n");
      delay(200);
    }
    printf("SIM808:set_gpsmode: send AT+CGNSSEQ OK!\n");
    serialPuts(fd,"AT+CGNSURC=0\r\n");//设置GPS输出参数
    while (judge_str("OK") == 0) {
      printf("SIM808:set_gpsmode: send AT+CGNSURC wait!\n");
      delay(200);
    }
    printf("SIM808:set_gpsmode: send AT+CGNSURC OK!\n");
    return 1;
  }
}

int SIM808::get_gpsdata(){//获取gps数据，并且拼接到短信内容中
  char *p;
  serialFlush(fd); //清空串口缓冲区
  delay(200);
  serialPuts(fd,"AT+CGNSINF\r\n");//等待定位成功
  printf("SIM808:get_gpsdata: AT+CGNSINF\n");
  delay(1000);//等待数据接收完全
  if (serialDataAvail(fd) > 0) {//串口有数据
    delay(200);
    read(fd,gps_inf,200);//读取串口数据
    i = 0;
    while (gps_inf[i] != 0) { //打印接受到的数据
      printf("%c",gps_inf[i]);
      i++;
    }
    printf("\nSIM808:get_gpsdata: recv data success!");
    p = (char *)strstr(gps_inf, "OK"); //寻找成功标志
    if (p != NULL) {
      *p = 0; //设定结束标志，去除“OK”
      p = (char *)strtok(gps_inf, ","); //根据“,”分割字符串
      p = (char *)strtok(NULL, ",");
      p = (char *)strtok(NULL, ","); //此时p指向的是时间
      printf("SIM808:get_gpsdata: time: "); printf(p);printf("\n");
      p = (char *)strtok(NULL, ","); //纬度
      printf("SIM808:get_gpsdata: latitude: "); printf(p);printf("\n");
      strcat(content, "\n  latitude:");
      strcat(content, p);
      p = (char *)strtok(NULL, ","); //经度
      printf("SIM808:get_gpsdata: longitude: "); printf(p);printf("\n");
      strcat(content, "\n  longitude:");
      strcat(content, p);
      p = (char *)strtok(NULL, ","); //海拔
      printf("SIM808:get_gpsdata: elevation: "); printf(p);printf("\n");
      strcat(content, "\n  elevation:");
      strcat(content, p);
      return 1;
    }
    else {
      return 0;
    }
  }
  else {
    return 0;
  }
}

void SIM808::send_sms(char *p){
  serialPuts(fd,sms_com);//号码
  delay(1000);
  printf("SIM808:send_sms: send AT+CMGS OK!\n");
  //strcat(p,"\r\n");
  serialPuts(fd,p);//短信内容发送
  delay(1000);
  serialPutchar(fd,0x1A);//发送一个字节的数据到串口
  delay(1000);
  while (judge_str("OK") == 0) {
    delay(1000);
  }
  /*while(serialDataAvail(fd) > 0){
	  serialGetchar(fd);
  }*/
  serialClose(fd);
  delay(200);
  fd=serialOpen("/dev/serial0",19200);//串口初始化
  delay(200);
  if(fd == -1){
	printf("SIM808:send_sms: Serial port initialization failed\n");
	return ;
  }
  printf("SIM808:send_sms: send xinxi OK!\n");
}

int SIM808::send_gpssms(){//发送带有gps信息的短信
  memset(content,0,sizeof(content));
  delay(200);
  strcpy(content, "I'm in trouble.I need your help.  \nGPS data:");
  if (get_gpsdata() == 0) {
    printf("SIM808:send_sms: get_gps_data error!");
    return 0;
  }
  else {
    int i = 0;
    while (content[i] != 0) { //打印接受到的数据
      printf("%c",content[i]);
      i++;
    }
	printf("\n");
    send_sms(content);
    return 1;
  }
}

int SIM808::call_phone(){//拨打电话
	serialPuts(fd,call_com);//拨打电话
	printf("SIM808:send_sms: Make a phone call\n");
	/*while (judge_str("OK") == 0) {
      printf("send call phone wait!\n");
      delay(200);
    }*/
  printf("\nSIM808:send_sms: call phone success!\n");
	return 1;
}

int SIM808::close_phone(){
	serialPuts(fd,"ATH\r\n");
	/*while (judge_str("OK") == 0) {
        printf("send ATH wait!\n");
        delay(200);
    }*/
  printf("\nSIM808:close_phone: send ATH OK!\n");
	return 1;
}

int SIM808::answer_phone(){
	serialPuts(fd,"ATA\r\n");
	/*while (judge_str("OK") == 0) {
        printf("send ATH wait!\n");
        delay(200);
    }*/
  printf("\nSIM808:answer_phone: send ATA OK!\n");
	return 1;
}
